home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / hotspot / viewer / movie.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-05  |  10.9 KB  |  325 lines

  1. /**************************************************************************
  2.  *
  3.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6.  *  PURPOSE.
  7.  *
  8.  *  Copyright (c) 1993  Microsoft Corporation.  All Rights Reserved.
  9.  * 
  10.  **************************************************************************/
  11. /*
  12.     movie.c:
  13.         positionMovie -- puts movie in upper left corner of window
  14.         fileCloseMovie -- closes movie & clears fPlaying and fMovieOpen
  15.         GetMovieLength -- returns number of frames in movie
  16.         GetMovieFrame -- returns current frame of movie
  17.         fileOpenMovie -- opens an AVI movie, optionally using a common
  18.             dialog box.  Movie is displayed paused when opened.
  19.         playMovie -- plays or pauses the movie
  20.         setMovie -- sets movie to specified frame
  21.         seekMovie -- go to beginning or end of movie
  22.         stepMovie -- go forwards or backwards one frame
  23. */
  24.  
  25. #include <windows.h>
  26. #include <mmsystem.h>
  27. #include <digitalv.h>       
  28. #include <viewer.h>
  29.  
  30. #include "hotspot.h"
  31.  
  32. /*
  33.     positionMovie -- gets the client rect of the parent window, gets the
  34.         size of the movie with MCI_WHERE, sets up a rect for the movie
  35.         to go in, and calls MoveWindow to move the child window,
  36.         and the movie, there.
  37. */
  38. VOID positionMovie(PMOVIEINFO pMovieInfo)
  39. {
  40.    RECT rcClient, rcMovieBounds;
  41.    MCI_DGV_RECT_PARMS   mciRect;
  42.    BOOL retcode = TRUE;
  43.    
  44.    /* if there is no movie yet then just get out of here */
  45.    if (!pMovieInfo->fMovieOpen)
  46.        return;
  47.    
  48.    GetClientRect(pMovieInfo->hwndParent, &rcClient);  /* get the parent windows rect */
  49.        
  50.    /* get the original size of the movie */
  51.    mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_WHERE, 
  52.                   (DWORD)(MCI_DGV_WHERE_SOURCE), 
  53.                   (DWORD)(LPMCI_DGV_RECT_PARMS)&mciRect);
  54.  
  55.    rcMovieBounds = mciRect.rc;  /* get it in the movie bounds rect */
  56.    // commented-out code to center movie...
  57.    //pMovieInfo->rcMovie.left = (rcClient.right/2) - (rcMovieBounds.right / 2);
  58.    //pMovieInfo->rcMovie.top = (rcClient.bottom/2) - (rcMovieBounds.bottom / 2);
  59.    pMovieInfo->rcMovie.left = 0;
  60.    pMovieInfo->rcMovie.top = 0;
  61.    pMovieInfo->rcMovie.right = pMovieInfo->rcMovie.left + rcMovieBounds.right;
  62.    pMovieInfo->rcMovie.bottom = pMovieInfo->rcMovie.top + rcMovieBounds.bottom;
  63.    
  64.    /* reposition the playback (child) window */
  65.    MoveWindow(pMovieInfo->hwndMovie, pMovieInfo->rcMovie.left, pMovieInfo->rcMovie.top,
  66.        rcMovieBounds.right, rcMovieBounds.bottom, TRUE);
  67. }
  68.  
  69. /*
  70.     fileCloseMovie -- uses MCI_CLOSE to close the movie, and
  71.         InvalidateRect to make the movie actually disappear from
  72.         the screen.
  73. */
  74. void fileCloseMovie(PMOVIEINFO pMovieInfo, BOOL bUpdate)
  75. {
  76.   MCI_GENERIC_PARMS  mciGeneric;
  77.   
  78.   pMovieInfo->fPlaying = FALSE; // can't be playing any longer
  79.   pMovieInfo->fMovieOpen = FALSE;   // no more movies open
  80.   
  81.   mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_CLOSE, MCI_WAIT, 
  82.                  (DWORD)(LPMCI_GENERIC_PARMS)&mciGeneric);
  83.                  
  84.   if (bUpdate)
  85.     {    
  86.     /* cause a total repaint to occur */
  87.     InvalidateRect(pMovieInfo->hwndParent, NULL, TRUE);
  88.     UpdateWindow(pMovieInfo->hwndParent);
  89.     }
  90. }
  91.  
  92. /*
  93.     GetMovieLength -- uses MCI_STATUS to find out number of frames in
  94.         movie.
  95. */
  96. DWORD GetMovieLength(PMOVIEINFO pMovieInfo)
  97. {
  98.     MCI_STATUS_PARMS mciStatus;
  99.  
  100.     mciStatus.dwTrack = 1;
  101.     mciStatus.dwCallback = NULL;
  102.     mciStatus.dwItem = MCI_STATUS_LENGTH;
  103.  
  104.     if (0 != (mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_STATUS, (DWORD)MCI_STATUS_ITEM,
  105.             (DWORD)(LPMCI_STATUS_PARMS)&mciStatus)))
  106.         {
  107.         dbg("Error getting movie length");
  108.         return 0;
  109.         }
  110.             
  111.     return (mciStatus.dwReturn);
  112. }
  113.  
  114. /*
  115.     GetMovieFrame -- uses MCI_STATUS to get current frame of movie.
  116. */
  117. DWORD GetMovieFrame(PMOVIEINFO pMovieInfo)
  118. {
  119.     MCI_STATUS_PARMS mciStatus;
  120.  
  121.     mciStatus.dwTrack = 1;
  122.     mciStatus.dwCallback = NULL;
  123.     mciStatus.dwItem = MCI_STATUS_POSITION;
  124.  
  125.     if (0 != (mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_STATUS, (DWORD)MCI_STATUS_ITEM,
  126.             (DWORD)(LPMCI_STATUS_PARMS)&mciStatus)))
  127.         {
  128.         dbg("Error getting movie frame");
  129.         return 0;
  130.         }
  131.             
  132.     return (mciStatus.dwReturn);            
  133. }
  134.  
  135. /*
  136.     fileOpenMovie --
  137.         uses MCI_OPEN to open the AVI file. Saves the device ID so we
  138.             can do stuff like find the frame size.
  139.         uses MCI_WINDOW to show the playback window
  140.         uses MCI_DGV_STATUS_HWND to get a handle to the window
  141.         gets the movie length with GetMovieLength, and
  142.         positions the movie with positionMovie.
  143.         Uses InvalidateRect to get window repainted (which will show
  144.         the first frame)
  145.         
  146.         Gives user an annoying messagebox if this doesn't work.
  147.         
  148. */
  149. void fileOpenMovie(PMOVIEINFO pMovieInfo, LPSTR szFilename)
  150. {
  151.    
  152.     if (pMovieInfo == NULL)
  153.         {
  154.         dbg("No MOVIEINFO for specified movie when trying to open AVI file.");
  155.         return;
  156.         }
  157.  
  158.    if (lstrlen(szFilename)){
  159.      MCI_DGV_OPEN_PARMS mciOpen;
  160.      MCI_DGV_WINDOW_PARMS   mciWindow;
  161.      MCI_DGV_STATUS_PARMS   mciStatus;
  162.  
  163.      /* we got a filename, now close any old movie and open */
  164.      /* the new one.                    */
  165.      if (pMovieInfo->fMovieOpen)
  166.          fileCloseMovie(pMovieInfo, TRUE);
  167.      
  168.      /* we have a .AVI movie to open, use MCI */
  169.      /* set up the open parameters */
  170.      mciOpen.dwCallback = NULL;
  171.      mciOpen.wDeviceID = mciOpen.wReserved0 =
  172.          mciOpen.wReserved1 = 0;
  173.      mciOpen.lpstrDeviceType = NULL;
  174.      mciOpen.lpstrElementName = szFilename;
  175.      mciOpen.lpstrAlias = NULL;
  176.      mciOpen.dwStyle = WS_CHILD;
  177.      mciOpen.hWndParent = pMovieInfo->hwndParent;
  178.  
  179.      /* try to open the file */
  180.      if (mciSendCommand(0, MCI_OPEN, 
  181.          (DWORD)(MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_DGV_OPEN_WS), 
  182.        (DWORD)(LPMCI_DGV_OPEN_PARMS)&mciOpen) == 0){
  183.  
  184.          /* we opened the file o.k., now set up to */
  185.          /* play it.                   */
  186.          pMovieInfo->wMCIDeviceID = mciOpen.wDeviceID;  /* save ID */
  187.          pMovieInfo->fMovieOpen = TRUE; /* a movie was opened */
  188.  
  189.          /* show the playback window */
  190.          mciWindow.dwCallback = NULL;
  191.          mciWindow.hWnd = NULL;
  192.          mciWindow.wReserved1 = mciWindow.wReserved2 = 0;
  193.          mciWindow.nCmdShow = SW_SHOW;
  194.          mciWindow.lpstrText = (LPSTR)NULL;
  195.          mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_WINDOW, 
  196.              MCI_DGV_WINDOW_STATE, 
  197.              (DWORD)(LPMCI_DGV_WINDOW_PARMS)&mciWindow);
  198.  
  199.          /* get the window handle */
  200.          mciStatus.dwItem = MCI_DGV_STATUS_HWND;
  201.          mciSendCommand(pMovieInfo->wMCIDeviceID, 
  202.              MCI_STATUS, MCI_STATUS_ITEM,
  203.              (DWORD)(LPMCI_STATUS_PARMS)&mciStatus);
  204.          pMovieInfo->hwndMovie = (HWND)mciStatus.dwReturn;
  205.          
  206.          /* get movie length */         
  207.          pMovieInfo->dwMovieLength = GetMovieLength(pMovieInfo);         
  208.          pMovieInfo->dwCurrentFrame = 0;
  209.                   
  210.          /* now get the movie centered */
  211.          positionMovie(pMovieInfo);
  212.      } else {
  213.         /* generic error for open */
  214.         MessageBox(pMovieInfo->hwndParent, "Unable to open Movie", NULL, 
  215.                   MB_ICONEXCLAMATION|MB_OK);
  216.         pMovieInfo->fMovieOpen = FALSE;
  217.      }
  218.    }
  219.    
  220.    /* cause an update to occur */
  221.    InvalidateRect(pMovieInfo->hwndParent, NULL, FALSE);
  222.    UpdateWindow(pMovieInfo->hwndParent);
  223. }
  224.  
  225. /*
  226.     playMovie -- looks at wDirection parameter and
  227.         sends MCI a MCI_PLAY command (optionally with
  228.             MCI_DGV_PLAY_REVERSE flag set) OR
  229.         sends MCI a MCI_PAUSE command
  230. */
  231. void playMovie(PMOVIEINFO pMovieInfo, WORD wDirection)
  232. {
  233.    pMovieInfo->fPlaying = !pMovieInfo->fPlaying;    /* swap the play flag */
  234.    if (wDirection == NULL)
  235.        pMovieInfo->fPlaying = FALSE;    /* wDirection == NULL means PAUSE */
  236.  
  237.    /* play/pause the AVI movie */
  238.    if (pMovieInfo->fPlaying){       
  239.        MCI_DGV_PLAY_PARMS   mciPlay;
  240.        DWORD dwFlags = MCI_NOTIFY;       
  241.            
  242.        /* init to play all */
  243.        mciPlay.dwCallback = MAKELONG(pMovieInfo->hwndMovie,0);
  244.        mciPlay.dwFrom = mciPlay.dwTo = 0;       
  245.        if (wDirection == 2)
  246.            dwFlags |= MCI_DGV_PLAY_REVERSE;
  247.        
  248.        mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_PLAY, dwFlags,
  249.                        (DWORD)(LPMCI_DGV_PLAY_PARMS)&mciPlay);
  250.    } else {
  251.        MCI_DGV_PAUSE_PARMS  mciPause;
  252.                         
  253.        /* tell it to pause */
  254.        mciSendCommand(pMovieInfo->wMCIDeviceID,MCI_PAUSE,MCI_WAIT,
  255.                      (DWORD)(LPMCI_DGV_PAUSE_PARMS)&mciPause);
  256.    }
  257. }
  258.  
  259. /*
  260.     setMovie -- stops movie if it is playing,
  261.         sends MCI an MCI_SEEK command to the frame number passed in.
  262. */
  263. void setMovie(PMOVIEINFO pMovieInfo, DWORD dwFrame, HWND hCallback)
  264. {   
  265.     MCI_SEEK_PARMS mciSeek;
  266.     
  267.     if (pMovieInfo->fPlaying){
  268.                         playMovie(pMovieInfo, NULL);   
  269.                         }                    
  270.     
  271.     mciSeek.dwTo = dwFrame;
  272.     mciSeek.dwCallback = MAKELONG(pMovieInfo->hwndMovie,0);
  273.     mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_SEEK, MCI_TO | MCI_WAIT,
  274.                         (DWORD)(LPMCI_SEEK_PARMS)&mciSeek);                    
  275. }
  276.  
  277. /*
  278.     seekMovie -- stops movie if playing, then goes to beginning or
  279.         end of movie. wAction == 0 means beginning, == 1 means end.
  280.         it does this my using MCI_SEEK with MCI_SEEK_TO_START or
  281.         MCI_SEEK_TO_END.
  282. */
  283. void seekMovie(PMOVIEINFO pMovieInfo, WORD wAction)
  284. {
  285.    /* first stop the movie from playing if it is playing */
  286.    if (pMovieInfo->fPlaying){
  287.        playMovie(pMovieInfo, NULL);   
  288.    }
  289.    if (wAction == 0){
  290.        /* home the movie */
  291.        mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_SEEK, MCI_SEEK_TO_START, 
  292.             (DWORD)(LPVOID)NULL);
  293.             
  294.    } else if (wAction == 1){
  295.        /* go to the end of the movie */
  296.        mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_SEEK, MCI_SEEK_TO_END, 
  297.             (DWORD)(LPVOID)NULL);
  298.    } 
  299. }
  300.  
  301. /*
  302.     stepMovie -- stops movie if playing, then steps one frame:
  303.         wDirection == MCI_STEP means forward, anything else means reverse.
  304.         it does this by using MCI_STEP command with MCI_DGV_STEP_FRAMES,
  305.         optionally with MCI_DGV_STEP_REVERSE flag set
  306.         
  307. */
  308. void stepMovie(PMOVIEINFO pMovieInfo, HWND hWnd, WORD wDirection)
  309. {
  310.    MCI_DGV_STEP_PARMS   mciStep;
  311.    
  312.    if (pMovieInfo->fPlaying)
  313.        playMovie(pMovieInfo, NULL);  /* turn off the movie */
  314.    
  315.        
  316.    mciStep.dwFrames = 1L;
  317.    if (wDirection == MCI_STEP)
  318.        mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_STEP, MCI_DGV_STEP_FRAMES,
  319.            (DWORD)(LPMCI_DGV_STEP_PARMS)&mciStep);
  320.    else
  321.        mciSendCommand(pMovieInfo->wMCIDeviceID, MCI_STEP, 
  322.            MCI_DGV_STEP_FRAMES|MCI_DGV_STEP_REVERSE,
  323.            (DWORD)(LPMCI_DGV_STEP_PARMS)&mciStep);
  324. }
  325.